# _*_ coding : utf-8 _*_
# @Time : 2022/9/15 17:44
# @Author : Moonquake
# @File : Portscan
# @Project : Portscan.py
import re
import sys
import socket
from queue import Queue
from threading import Thread,Lock
Lock = Lock()
works = Queue()
TH_NUM = 0
IP = ''
IP_RANGE = []
PORT_RANGE = []  # 端口范围

# 解析IP地址
IP_Value = sys.argv[1]
# IP格式正则 (0-255).(0-255).(0-255).(0-255)
regex = re.compile(r'(([1-9]?\d|1\d\d|2[0-4]\d|25[0-5])\.){3}([1-9]?\d|1\d\d|2[0-4]\d|25[0-5])')
# 判断IP还是IP段
if IP_Value.find('-') != -1:
    if regex.match(IP_Value.split('-')[0]):
        Part = IP_Value.split('-')[0].split('.')[0] + '.' +IP_Value.split('-')[0].split('.')[1] + '.' +IP_Value.split('-')[0].split('.')[2] + '.'  # 192.168.1.
        start_ip = int(IP_Value.split('-')[0].split('.')[3])
        end_ip = int(IP_Value.split('-')[1])
        for i in range(start_ip,end_ip+1):
            IP_RANGE.append(Part + str(i))
    else:
        print('输入的IP不合法')
        exit(1)
else:
    if regex.match(IP_Value):
        IP = IP_Value  # 单个IP
        IP_RANGE.append(IP)
        print(IP)
    else:
        print('输入的IP不合法')
        exit(1)

# 解析端口范围
PORT_Value = sys.argv[2]
start_port = int(PORT_Value.split('-')[0])
end_port = int(PORT_Value.split('-')[1])

# 判断端口输入
if start_port > 65535 or end_port > 65535:
    print('输入的端口范围不合法')
    exit(1)
for p in range(start_port, end_port+1):
    PORT_RANGE.append(p)              # 将端口逐个写入到PORTRANGE

# 解析线程数
THUNM_Value = int(sys.argv[3])
if THUNM_Value <= 0:
    print('指定的端口数不合法')
    exit(1)
TH_NUM = THUNM_Value
print(TH_NUM)


def boss():
    global IP_RANGE, PORT_RANGE
    for ip in IP_RANGE:
        for port in PORT_RANGE:
            works.put((ip, port))


def worker():
    while True:
        address = works.get()
        st = socket.socket()
        st.settimeout(1)
        if st.connect_ex(address) == 0:
            Lock.acquire()
            print(f'【*】 IP:\t{address[0]}\t端口:\t[{address[1]}]\t【开放】')
            Lock.release()
        st.close()
        works.task_done()


p = Thread(target=boss)
p.daemon = True
p.start()

for _ in range(TH_NUM):
    t=Thread(target=worker)
    t.daemon= True
    t.start()

works.join()




